/**
 * TraceReader.java:<p>
 * Reads and parses specified .gpx file; sends latitude and longitude data to
 * specified web service along with timestamp
 * 
 * @author Niko Simonson (CSS 590, University of Washington, Bothell)
 * @since 5/8/13
 * @version NS130511
 */
package TraceReader;

import java.io.*;
import java.util.Date;
import org.json.simple.*;
import java.text.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.HttpClient;
import org.apache.http.entity.StringEntity;
import org.apache.http.params.HttpConnectionParams;

public class TraceReader implements Runnable {
    
    String address;
    String filepath;
    int offenderID;
    
    public TraceReader(String target, String path, int oid) {
        
        address = target;
        filepath = path;
        offenderID = oid;
    }
    
    public void run() {
        // JSON object names
        final String JSONLAT = "lat";
        final String JSONLON = "lon";
        final String JSONTIME = "time";
        final String JSONOFFID = "offender";
        final int MILLISECONDDELAY = 300;

        // VARIABLE DECLARATIONS
        BufferedReader br = null; // reads a file
        String sCurrentLine = "";
        String lat = ""; // latitude
        String lon = ""; // longitude

        // helper variables for parsing
        int offset = 0;
        char testChar;
        Boolean first = false;
        Boolean second = false;

        // variables for sending data
        Date currentTime = null; // helper variable for time lag
        Date sendTime = null;
        JSONObject trace = null; // data sent as JSON object

        try {
            // construct objects
            trace = new JSONObject();
            currentTime = new Date();

            // point to GPS trace
            br = new BufferedReader(new FileReader(filepath));

            // read GPS trace line by line
            while ((sCurrentLine = br.readLine()) != null) {
                // skip white space
                while (sCurrentLine.startsWith(" ", offset) || sCurrentLine.startsWith("\t", offset)) {
                    ++offset;
                }
                // <trkpt> contains latitude and longitude information
                if (sCurrentLine.startsWith("<trkpt", offset) || sCurrentLine.startsWith("<rtept", offset)) {
                    // scan line character by character
                    for (int i = offset; i < sCurrentLine.length(); ++i) {
                        testChar = sCurrentLine.charAt(i);
                        // test for numbers
                        if (Character.isDigit(testChar)
                                || (testChar == '-')
                                || (testChar == '.')) {
                            // flag the first number in the line
                            if (!first)
                                first = true;
                            // the first number is the latitude
                            if (first && !second) 
                                lat += testChar;
                            // the second number is the longitude
                            if (second)
                                lon += testChar;
                        } 
                        // flag the second number in the line
                        else if (first && !second) {
                            second = true;
                        }
                    } // next
                    sendTime = new Date();

                    // busy wait
                    while (currentTime.getSeconds() == sendTime.getSeconds()) {
                        sendTime = new Date();
                    }


                    //configure JSON object
                    trace = new JSONObject();
                    trace.put(JSONLON, lon);
                    trace.put(JSONLAT, lat);
                    trace.put(JSONOFFID, offenderID);
                    
                    String convertedDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(sendTime);
                    
                    trace.put(JSONTIME, convertedDate.toString());

                    HttpClient httpClient = new DefaultHttpClient();
                    try {
                        
                        HttpPost request = new HttpPost(address);
                        StringEntity params = new StringEntity(trace.toString());
                        request.addHeader("content-type", "application/x-www-form-urlencoded");
                        request.setEntity(params);
                        HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), MILLISECONDDELAY);
                        HttpConnectionParams.setSoTimeout(httpClient.getParams(), MILLISECONDDELAY);
                        
                        //handle response here
                        HttpResponse response = httpClient.execute(request);
                    } catch (Exception e) {
                    } finally {
                        httpClient.getConnectionManager().shutdown();
                    }
                    // TEST PRINT JSON Object
                    System.out.println(trace.toString());
                    
                    // reinitialize
                    lat = "";
                    lon = "";
                    first = false;
                    second = false;
                    currentTime = sendTime;
                } // end if trkpt line
                // reset offset
                offset = 0;
            } // end line scan loop
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}